package fr.umlv.escapeir.game;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

import org.jbox2d.callbacks.ContactListener;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.World;
import org.jbox2d.dynamics.contacts.Contact;

public class WorldContactListener {
	
	private WorldContactListener () {}
	
	public static void createForWorld(World world) {
		InvocationHandler handler = new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				
				Class<?> paramTypes[] = method.getParameterTypes();
				if (paramTypes.length <= 0 || paramTypes[0] != Contact.class) return Void.TYPE;
				
				Contact contact = null;
				try {
					contact = Contact.class.cast(args[0]);
				} catch (ClassCastException e) {
					return Void.TYPE;
				}
				
				Body bb = contact.getFixtureB().getBody();
				ContactListener clb;
				try {
					clb = ContactListener.class.cast(bb.m_userData);
					if (clb != null) method.invoke(clb, args);
				} catch (ClassCastException e) {}
				
				Body ba = contact.getFixtureA().getBody();
				ContactListener cla;
				try {
					cla = ContactListener.class.cast(ba.m_userData);
					if (cla != null) method.invoke(cla, args);
				} catch (ClassCastException e) {}
				
				return Void.TYPE;
			}
		};
		
		ContactListener cl = (ContactListener)Proxy.newProxyInstance(
									ContactListener.class.getClassLoader(),
									new Class<?>[]{ContactListener.class},
									handler);
		
		world.setContactListener(cl);
	}
}
